home *** CD-ROM | disk | FTP | other *** search
- /***************************************************************
-
- bwbasic.c Main Program File
- for Bywater BASIC Interpreter
-
- Copyright (c) 1992, Ted A. Campbell
-
- "I was no programmer, neither was I a
- programmer's son; but I was an herdman
- and a gatherer of sycomore fruit."
- - Amos 7:14b AV, slightly adapted
-
- Bywater Software
- P. O. Box 4023
- Duke Station
- Durham, NC 27706
-
- email: tcamp@acpub.duke.edu
-
- Copyright and Permissions Information:
-
- All U.S. and international copyrights are claimed by the
- author. The author grants permission to use this code
- and software based on it under the following conditions:
- (a) in general, the code and software based upon it may be
- used by individuals and by non-profit organizations; (b) it
- may also be utilized by governmental agencies in any country,
- with the exception of military agencies; (c) the code and/or
- software based upon it may not be sold for a profit without
- an explicit and specific permission from the author, except
- that a minimal fee may be charged for media on which it is
- copied, and for copying and handling; (d) the code must be
- distributed in the form in which it has been released by the
- author; and (e) the code and software based upon it may not
- be used for illegal activities.
-
- ***************************************************************/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include <string.h>
- #include <math.h>
- #include <signal.h>
- #include <setjmp.h>
-
- #include "bwbasic.h"
- #include "bwb_mes.h"
-
- char bwb_progfile[ MAXARGSIZE ];
- struct bwb_line bwb_start, bwb_end;
- char *bwb_ebuf; /* error buffer */
- static char *read_line;
- int bwb_trace = FALSE;
- int bwb_number = 0;
- struct bwb_line *bwb_l;
-
- struct xtxtsl
- {
- int position;
- struct bwb_line l;
- };
-
- struct xtxtsl *xtxts; /* eXecute TeXT stack */
- struct exp_ese *exp_es; /* expression stack */
- struct ufsel *ufs; /* user function stack */
- struct fse *fs; /* FOR stack */
-
- int xtxtsc = -1; /* eXecute TeXT stack counter */
-
- FILE *errfdevice; /* output device for error messages */
- static jmp_buf mark;
- static int program_run = FALSE; /* has the command-line program ben run? */
-
- /* Prototypes for functions visible only to this file */
-
- #if COMMAND_SHELL
- static int bwb_shell( struct bwb_line *l );
- #endif
-
- extern int is_ln( char *buffer );
-
- /***************************************************************
-
- FUNCTION: main()
-
- DESCRIPTION: As in any C program, main() is the basic
- function from which the rest of the
- program is called.
-
- PRAYER: Everlasting God,
-
- Thine eternal Logos is the main() function
- from which all things have their being
- and unto which all things shall return;
- all subroutines are restless until they
- find their rest in thee.
-
- Grant that users of this software may
- apply it for good purposes; grant
- unto programmers searching its ways that
- they may not be entirely confounded; and
- grant that all our work may be unto thy
- glory. Amen.
-
- ***************************************************************/
-
- void
- main( int argc, char **argv )
- {
- static FILE *input = NULL;
- static int jump_set = FALSE;
- static char start_buf[] = "\0";
- static char end_buf[] = "\0";
- register int n;
- #if REDIRECT_STDERR
- FILE *newerr;
- #endif
-
- /* set some initial variables */
-
- bwb_start.number = 0;
- bwb_start.next = &bwb_end;
- bwb_end.number = MAXLINENO + 1;
- bwb_end.next = &bwb_end;
- bwb_start.buffer = start_buf;
- bwb_end.buffer = end_buf;
- data_line = &bwb_start;
- data_pos = 0;
-
- /* Memory allocation for various tables */
-
- /* eXecute TeXT stack */
-
- if ( ( xtxts = calloc( XTXTSTACKSIZE, sizeof( struct xtxtsl ) ) ) == NULL )
- {
- bwb_error( err_getmem );
- }
-
- /* expression stack */
-
- if ( ( exp_es = calloc( ESTACKSIZE, sizeof( struct exp_ese ) ) ) == NULL )
- {
- bwb_error( err_getmem );
- }
-
- /* user-defined function stack */
-
- if ( ( ufs = calloc( UFNCSTACKSIZE, sizeof( struct ufsel ) ) ) == NULL )
- {
- bwb_error( err_getmem );
- }
-
- /* FOR-NEXT stack */
-
- if ( ( fs = calloc( FORLEVELS, sizeof( struct fse ) ) ) == NULL )
- {
- bwb_error( err_getmem );
- }
-
- /* GOSUB-RETURN stack */
-
- if ( ( bwb_gss = calloc( GOSUBLEVELS, sizeof( struct gsse ) ) ) == NULL )
- {
- bwb_error( err_getmem );
- }
-
- /* character buffers */
-
- if ( ( bwb_ebuf = calloc( MAXSTRINGSIZE + 1, sizeof(char) ) ) == NULL )
- {
- bwb_error( err_getmem );
- }
- if ( ( read_line = calloc( MAXREADLINESIZE + 1, sizeof(char) ) ) == NULL )
- {
- bwb_error( err_getmem );
- }
-
- /* Variable and function table initializations */
-
- var_init(); /* initialize variable chain */
-
- fnc_init(); /* initialize function chain */
-
- #if TEST_BSTRING
- for ( n = 0; n < ESTACKSIZE; ++n )
- {
- sprintf( exp_es[ n ].sval.name, "<Exp stack bstring %d>", n );
- }
- #endif
-
- /* assign memory for the device table */
-
- if ( ( dev_table = calloc( DEF_DEVICES, sizeof( struct dev_element ) ) ) == NULL )
- {
- bwb_error( err_getmem );
- exit(-1);
- }
-
- /* initialize all devices to DEVMODE_AVAILABLE */
-
- for ( n = 0; n < DEF_DEVICES; ++n )
- {
- dev_table[ n ].mode = DEVMODE_AVAILABLE;
- dev_table[ n ].reclen = -1;
- dev_table[ n ].cfp = NULL;
- dev_table[ n ].buffer = NULL;
- dev_table[ n ].width = DEF_WIDTH;
- dev_table[ n ].col = 1;
- }
-
- /* Signon message */
-
- sprintf( bwb_ebuf, "\r%s %s\n", MES_SIGNON, VERSION );
- xprintf( stdout, bwb_ebuf );
- sprintf( bwb_ebuf, "\r%s\n", MES_COPYRIGHT );
- xprintf( stdout, bwb_ebuf );
- #if PERMANENT_DEBUG
- sprintf( bwb_ebuf, "\r%s\n", "DEBUGGING MODE" );
- xprintf( stdout, bwb_ebuf );
- #else
- sprintf( bwb_ebuf, "\r%s\n", MES_LANGUAGE );
- xprintf( stdout, bwb_ebuf );
- #endif
-
- /* Redirect stderr if specified */
-
- #if REDIRECT_STDERR
- newerr = freopen( ERRFILE, "w", stderr );
- if ( newerr == NULL )
- {
- sprintf( bwb_ebuf, "Failed to redirect error messages to file <%s>\n",
- ERRFILE );
- xprintf( stdout, bwb_ebuf );
- errfdevice = stdout;
- }
- else
- {
- sprintf( bwb_ebuf, "NOTE: Error messages are redirected to file <%s>\n",
- ERRFILE );
- xprintf( errfdevice, bwb_ebuf );
- errfdevice = stderr;
- }
- #else
- errfdevice = stdout;
- #endif
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in main(): Ready to save jump MARKER" );
- bwb_debug( bwb_ebuf );
- getchar();
- #endif
-
- /* set a buffer for jump: program execution returns to this point
- in case of a jump (error, interrupt, or finish program) */
-
- signal( SIGINT, break_mes );
- setjmp( mark );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in main(): Return from jump MARKER, program run <%d>",
- program_run );
- bwb_debug( bwb_ebuf );
- getchar();
- #endif
-
- /* check to see if there is a program file: but do this only the first
- time around! */
-
- if (( argc > 1 ) && ( program_run == FALSE ))
- {
- program_run = TRUE; /* don't do it again */
- if ( ( input = fopen( argv[ 1 ], "r" )) == NULL )
- {
- strcpy( bwb_progfile, argv[ 1 ] );
- strcat( bwb_progfile, ".bas" );
- if ( ( input = fopen( bwb_progfile, "r" )) == NULL )
- {
- bwb_progfile[ 0 ] = 0;
- sprintf( bwb_ebuf, err_openfile, argv[ 1 ] );
- bwb_error( bwb_ebuf );
- }
- }
- if ( input != NULL )
- {
- strcpy( bwb_progfile, argv[ 1 ] );
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in main(): progfile is <%s>.", bwb_progfile );
- bwb_debug( bwb_ebuf );
- #endif
- bwb_fload( input );
- bwb_run( &bwb_start );
- }
- }
-
- /* Main Program Loop */
-
- while( !feof( stdin ) ) /* condition !feof( stdin ) added in v1.11 */
- { /* to deal with possible of ^D etc. in Unix */
-
- /* take input from keyboard */
-
- bwb_gets( read_line );
-
- /* If there is no line number, execute the line as received */
-
- if ( is_ln( read_line ) == FALSE )
- {
- bwb_xtxtline( read_line );
- }
-
- /* If there is a line number, add the line to the file in memory */
-
- else
- {
- bwb_ladd( read_line, TRUE );
- }
-
- }
-
- }
-
- /***************************************************************
-
- FUNCTION: bwb_fload()
-
- DESCRIPTION: This function loads a BASIC program
- file into memory.
-
- ***************************************************************/
-
- bwb_fload( FILE *file )
- {
-
- while ( feof( file ) == FALSE )
- {
- read_line[ 0 ] = '\0';
- fgets( read_line, MAXREADLINESIZE, file );
- if ( file == stdin )
- {
- * prn_getcol( stdout ) = 1; /* reset column */
- }
- bwb_stripcr( read_line );
- bwb_ladd( read_line, FALSE );
- }
-
- /* close file stream */
-
- fclose( file );
-
- return TRUE;
- }
-
- /***************************************************************
-
- FUNCTION: bwb_ladd()
-
- DESCRIPTION: This function adds a new line (in the
- buffer) to the program in memory.
-
- ***************************************************************/
-
- bwb_ladd( char *buffer, int replace )
- {
- struct bwb_line *l, *previous;
- register int n, a;
- static char *s_buffer;
- static int init = FALSE;
- static int prev_num = 0;
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_ladd(): ready to get memory for <%s>",
- buffer );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* get memory for temporary buffer if necessary */
-
- if ( init == FALSE )
- {
- init = TRUE;
- if ( ( s_buffer = calloc( (size_t) MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL )
- {
- bwb_error( err_getmem );
- return FALSE;
- }
- }
-
- /* get memory for this line */
-
- if ( ( l = (struct bwb_line *) calloc( (size_t) 1, sizeof( struct bwb_line ) )) == NULL )
- {
- bwb_error( err_getmem );
- return FALSE;
- }
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_ladd(): got memory." );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* allocate memory and assign buffer to line buffer */
-
- ln_asbuf( l, buffer );
-
- /* get the first element and test for a line number */
-
- adv_element( l->buffer, &( l->position ), s_buffer );
-
- /* note that line is not yet marked */
-
- l->marked = FALSE;
-
- /* set line number in line structure */
-
- if ( is_numconst( s_buffer ) == TRUE )
- {
- l->number = atoi( s_buffer );
- prev_num = l->number;
- }
- else
- {
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_ladd(): line is not numbered, using prev <%d>",
- prev_num );
- bwb_debug( bwb_ebuf );
- #endif
-
- l->number = prev_num;
- }
-
- /* find the place of the current line */
-
- for ( previous = &bwb_start; previous != &bwb_end; previous = previous->next )
- {
-
- /* replace a previously existing line */
-
- if (( previous->number == l->number ) && ( replace == TRUE ))
- {
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_ladd(): writing to previous number." );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* allocate memory and assign buffer to line buffer */
-
- ln_asbuf( previous, buffer );
-
- /* free the current line */
-
- free( l );
-
- /* and return */
-
- return TRUE;
-
- }
-
- /* add after previously existing line: this is to allow unnumbered
- lines that follow in sequence after a previously numbered line */
-
- else if (( previous->number == l->number ) && ( replace == FALSE ))
- {
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_ladd(): adding doubled number <%d>",
- l->number );
- bwb_debug( bwb_ebuf);
- #endif
- l->next = previous->next;
- previous->next = l;
- return TRUE;
- }
-
- /* add a new line */
-
- else if ( ( previous->number < l->number )
- && ( previous->next->number > l->number ))
- {
- l->next = previous->next;
- previous->next = l;
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_ladd(): added new line <%d> buffer <%s>",
- l->number, l->buffer );
- bwb_debug( bwb_ebuf );
- #endif
-
- return TRUE;
- }
-
- }
-
- sprintf( bwb_ebuf, ERR_LINENO );
- bwb_error( bwb_ebuf );
- return FALSE;
-
- }
-
- /***************************************************************
-
- FUNCTION: bwb_shell()
-
- DESCRIPTION:
-
- ***************************************************************/
-
- #if COMMAND_SHELL
- static int
- bwb_shell( struct bwb_line *l )
- {
- static char *s_buffer;
- static int init = FALSE;
- static int position;
-
- /* get memory for temporary buffer if necessary */
-
- if ( init == FALSE )
- {
- init = TRUE;
- if ( ( s_buffer = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL )
- {
- bwb_error( err_getmem );
- return FALSE;
- }
- }
-
- /* get the first element and check for a line number */
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_shell(): line buffer is <%s>.", l->buffer );
- bwb_debug( bwb_ebuf );
- #endif
-
- position = 0;
- adv_element( l->buffer, &position, s_buffer );
- if ( is_numconst( s_buffer ) != TRUE ) /* not a line number */
- {
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_shell(): no line number, command <%s>.",
- l->buffer );
- bwb_debug( bwb_ebuf );
- #endif
-
- if ( system( l->buffer ) == 0 )
- {
- return TRUE;
- }
- else
- {
- return FALSE;
- }
- }
-
- else /* advance past line number */
- {
- adv_ws( l->buffer, &position ); /* advance past whitespace */
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_shell(): line number, command <%s>.",
- l->buffer );
- bwb_debug( bwb_ebuf );
- #endif
-
- if ( system( &( l->buffer[ position ] ) ) == 0 )
- {
- return TRUE;
- }
- else
- {
- return FALSE;
- }
- }
- }
- #endif
-
- /***************************************************************
-
- FUNCTION: bwb_xtxtline()
-
- DESCRIPTION: This function executes a text line, i.e.,
- places it in memory and then calls
- bwb_xline() to execute it.
-
- ***************************************************************/
-
- struct bwb_line *
- bwb_xtxtline( char *buffer )
- {
- struct bwb_line *c;
- register int n, a;
- char *p;
- int loop;
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_xtxtline(): received <%s>", buffer );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* increment xtxt stack counter */
-
- if ( xtxtsc >= XTXTSTACKSIZE )
- {
- sprintf( bwb_ebuf, "Exceeded maximum xtxt stack <%d>",
- xtxtsc );
- return &bwb_end;
- }
-
- ++xtxtsc;
-
- /* advance past whitespace */
-
- p = buffer;
- loop = TRUE;
- while( loop == TRUE )
- {
-
- switch( *p )
- {
- case '\0': /* end of string */
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "Null command line received." );
- bwb_debug( bwb_ebuf );
- #endif
- --xtxtsc;
- return &bwb_end;
- case ' ': /* whitespace */
- case '\t':
- ++p;
- break;
- default:
- loop = FALSE;
- break;
- }
-
- }
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_xtxtline(): ready to get memory" );
- bwb_debug( bwb_ebuf );
- #endif
-
- if ( xtxts[ xtxtsc ].l.buffer != NULL )
- {
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_xtxtline(): freeing buffer memory" );
- bwb_debug( bwb_ebuf );
- #endif
- free( xtxts[ xtxtsc ].l.buffer );
- }
-
- /* copy the whole line to the line structure buffer */
-
- ln_asbuf( &( xtxts[ xtxtsc ].l ), buffer );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_xtxtline(): copied to line buffer <%s>.",
- xtxts[ xtxtsc ].l.buffer );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* set line number in line structure */
-
- xtxts[ xtxtsc ].l.number = 0;
- xtxts[ xtxtsc ].l.marked = FALSE;
-
- /* execute the line as BASIC command line */
-
- xtxts[ xtxtsc ].l.next = &bwb_end;
- c = &( xtxts[ xtxtsc ].l );
- c->position = 0;
-
- do
- {
- /* xtxts[ xtxtsc ].position = 0; */
- c = bwb_xline( c );
- }
-
- while( c != &bwb_end );
-
- /* decrement xtxt stack counter */
-
- --xtxtsc;
-
- return c;
-
- }
-
- /***************************************************************
-
- FUNCTION: bwb_xline()
-
- DESCRIPTION: This function executes a single line of
- the program in memory.
-
- ***************************************************************/
-
- struct bwb_line *
- bwb_xline( struct bwb_line *l )
- {
- int loop, extended_line;
- struct bwb_line *r;
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_xline(): buffer <%s>",
- &( l->buffer[ l->position ] ) );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* Print line number if trace is on */
-
- if ( bwb_trace == TRUE )
- {
- if ( l->number > 0 )
- {
- sprintf( bwb_ebuf, "[ %d ]", l->number );
- xprintf( errfdevice, bwb_ebuf );
- }
- }
-
- /* Set current line for error/break handling */
-
- bwb_number = l->number;
- bwb_l = l;
- extended_line = FALSE;
-
- /* advance past whitespace and segment delimiter */
-
- if ( l->buffer[ l->position ] == ':' )
- {
- ++( l->position );
- }
- adv_ws( l->buffer, &( l->position ) );
- if ( l->buffer[ l->position ] == ':' )
- {
- ++( l->position );
- adv_ws( l->buffer, &( l->position ) );
- }
-
- /* Loop through line segments delimited by ':' */
-
- loop = TRUE;
- r = l->next;
-
- while ( loop == TRUE )
- {
-
- /* set loop to false: it will be set to TRUE later if needed */
-
- loop = FALSE;
-
- /* set positions in buffer */
-
- #if MARK_LINES
- if ( ( l->marked != TRUE ) || ( l->position > l->startpos ))
- {
- line_start( l->buffer, &( l->position ), &( l->lnpos ), &( l->lnum ),
- &( l->cmdpos ), &( l->cmdnum ), &( l->startpos ) );
- l->marked = TRUE;
- }
- else
- {
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_xline(): line <%d> is already marked",
- l->number );
- bwb_debug( bwb_ebuf );
- #endif
- }
- #else
- line_start( l->buffer, &( l->position ), &( l->lnpos ), &( l->lnum ),
- &( l->cmdpos ), &( l->cmdnum ), &( l->startpos ) );
- #endif
-
- if ( l->position < l->startpos )
- {
- l->position = l->startpos;
- }
-
- /* if there is a BASIC command in the line, execute it here */
-
- if ( l->cmdnum > -1 )
- {
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_xline(): executing <%s>", l->buffer );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* execute the command vector */
-
- r = ( bwb_cmdtable[ l->cmdnum ].vector ) ( l );
-
- #if INTENSIVE_DEBUG
- if ( l->cmdnum == getcmdnum( "GOSUB" ) )
- {
- sprintf( bwb_ebuf, "in bwb_xline(): returning from GOSUB, position <%d>",
- l->position );
- bwb_debug( bwb_ebuf );
- }
- #endif
-
- /* If the command was RETURN OR GOTO, then we must break out of
- the loop at this point; the rest of the line is irrelevant */
-
- if ( l->cmdnum == getcmdnum( "RETURN" ) )
- {
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_xline(): returning from RETURN command, ret line <%d>",
- r->number );
- bwb_debug( bwb_ebuf );
- #endif
- r->cmdnum = getcmdnum( "RETURN" );
- r->marked = FALSE;
- return r; /* break out; return now */
- }
-
- else if ( l->cmdnum == getcmdnum( "GOTO" ) )
- {
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_xline(): returning from GOTO command, ret line <%d>",
- r->number );
- bwb_debug( bwb_ebuf );
- #endif
- return r;
- }
- }
-
- else if ( l->buffer[ l->position ] == ':' )
- {
- l->marked = FALSE;
- } /* do nothing */
-
- /* No BASIC command; try to execute it as a shell command */
-
- #if COMMAND_SHELL
- else
- {
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "Breaking out to shell, line num <%d> buf <%s> cmd <%d> pos <%d>",
- l->number, &( l->buffer[ l->position ] ), l->cmdnum, l->position );
- bwb_debug( bwb_ebuf );
- getchar();
- #endif
-
- bwb_shell( l );
- }
-
- #else /* COMMAND_SHELL == FALSE */
-
- else
- {
- bwb_error( err_uc );
- }
-
- #endif
-
- /* detect if the current character is ':', in which case loop
- back through to execute it */
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_xline(): remaining line is <%s>",
- &( l->buffer[ l->position ] ) );
- bwb_debug( bwb_ebuf );
- #endif
-
- adv_ws( l->buffer, &( l->position ) );
- if ( l->buffer[ l->position ] == ':' )
- {
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in bwb_xline(): line <%d> found \':\'",
- l->number );
- bwb_debug( bwb_ebuf );
- #endif
-
- ++l->position;
- l->marked = FALSE;
- extended_line = TRUE;
- loop = TRUE;
- }
-
- else if ( extended_line == TRUE )
- {
- l->marked = FALSE;
- }
-
- } /* end of loop through line */
-
- /* return the value in r */
-
- #if INTENSIVE_DEBUG
- if ( r->cmdnum == getcmdnum( "RETURN" ) )
- {
- bwb_debug( "in bwb_xline(): returning RETURN cmdnum" );
- }
- #endif
-
- return r;
-
- }
-
- /***************************************************************
-
- FUNCTION: ln_asbuf()
-
- DESCRIPTION: This function allocates memory and copies
- a null-terminated string to a line buffer.
-
- ***************************************************************/
-
- int
- ln_asbuf( struct bwb_line *l, char *s )
- {
-
- #ifdef DONTDOIT
- if ( l->buffer != NULL )
- {
- free( l->buffer );
- }
- #endif
-
- if ( ( l->buffer = calloc( strlen( s ) + 2, sizeof( char ) ) )
- == NULL )
- {
- bwb_error( err_getmem );
- return FALSE;
- }
-
- /* copy the whole line to the line structure buffer */
-
- strcpy( l->buffer, s );
-
- #if INTENSIVE_DEBUG
- sprintf( bwb_ebuf, "in ln_asbuf(): allocated buffer <%s>", l->buffer );
- bwb_debug( bwb_ebuf );
- #endif
-
- /* strip CR from the buffer */
-
- bwb_stripcr( l->buffer );
-
- return TRUE;
-
- }
-
- /***************************************************************
-
- FUNCTION: bwb_gets()
-
- DESCRIPTION: This function reads a single line from
- the specified buffer.
-
- ***************************************************************/
-
- bwb_gets( char *buffer )
- {
- bwb_number = 0;
- sprintf( bwb_ebuf, "\r%s\n", PROMPT );
- xprintf( stdout, bwb_ebuf );
-
- fgets( buffer, MAXREADLINESIZE, stdin );
- * prn_getcol( stdout ) = 1; /* reset column */
- return TRUE;
- }
-
- /***************************************************************
-
- FUNCTION: break_mes()
-
- DESCRIPTION: This function is called (a) by a SIGINT
- signal or (b) by error-handling routines.
-
- ***************************************************************/
-
- void
- break_mes( int x )
- {
- static char *tmp_buffer;
- static int init = FALSE;
-
- /* get memory for temporary buffer if necessary */
-
- if ( init == FALSE )
- {
- init = TRUE;
- if ( ( tmp_buffer = calloc( MAXSTRINGSIZE + 1, sizeof( char ) )) == NULL )
- {
- bwb_error( err_getmem );
- }
- }
-
- exp_esc = 0;
-
- sprintf( tmp_buffer, "\r%s %d\n", MES_BREAK, bwb_number );
- xprintf( errfdevice, tmp_buffer );
-
- break_handler();
-
- }
-
- void
- break_handler( void )
- {
-
- /* zero all stack counters */
-
- exp_esc = 0;
- bwb_gssc = 0;
- ufsc = 0;
- ws_counter = 0;
- fs_counter = 0;
- xtxtsc = 0;
-
- /* reset the break handler */
-
- signal( SIGINT, break_mes );
-
- /* jump back to mark */
-
- longjmp( mark, -1 );
-
- }
-
-
- int
- is_ln( char *buffer )
- {
- static int position;
-
- position = 0;
- adv_ws( buffer, &position );
- switch( buffer[ position ] )
- {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- return TRUE;
- default:
- return FALSE;
- }
- }
-
-